//============================================================================
// Name        : cpp_http_client.cpp
// Author      : darkflash
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
using namespace std;

struct CallbackStruct{
	char* data;
	size_t size;
};

static size_t write_response(void *ptr, size_t size, size_t nmemb, void *stream){
		size_t realSize = size*nmemb;
	    struct CallbackStruct *callbackStruct = (struct CallbackStruct*)stream;

	    callbackStruct->data = (char*)realloc(callbackStruct->data, callbackStruct->size + realSize + 1);
	    if(callbackStruct->data == NULL){
	    	cout << "out of memory (realloc returned NULL)" << endl;
	    	return 0;
	    }

	    memcpy(&(callbackStruct->data[callbackStruct->size]), ptr, realSize);
	    callbackStruct->size += realSize;
	    callbackStruct->data[callbackStruct->size] = 0;

	    return realSize;
}



int main() {
	CURL *curl;
	CURLcode res;
	struct CallbackStruct headerStruct;
	struct CallbackStruct bodyStruct;
	long httpStatus;

	string input, userid, password;

	cout << "input url: ";
	getline(cin, input);
	cout << "userid: ";

	getline(cin, userid);
	if(!userid.empty()){
		cout << "password: ";
		getline(cin, password);
	}



	curl_global_init(CURL_GLOBAL_DEFAULT);
	curl = curl_easy_init();
	if(curl){
		headerStruct.data = (char*)malloc(1);
		bodyStruct.data = (char*)malloc(1);

		headerStruct.size = 0;
		bodyStruct.size = 0;

		curl_easy_setopt(curl, CURLOPT_URL, input.c_str());

		curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&bodyStruct);
		curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_response);
		curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void*)&headerStruct);

		if(!userid.empty()){
			curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
			curl_easy_setopt(curl, CURLOPT_USERPWD, (userid+":"+password).c_str());
		}

		res = curl_easy_perform(curl);

		curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpStatus);

		/* always cleanup */
		curl_easy_cleanup(curl);

		if(CURLE_OK != res) {
			/* we failed */
			fprintf(stderr, "curl told us %d\n", res);
		}
	}

	curl_global_cleanup();
//
	cout << ">>>>>>>>>>>> header" << endl;
	cout << headerStruct.data << endl;
	cout << ">>>>>>>>>>>> body" << endl;
	cout << bodyStruct.data << endl;

	cout << ">>>>>>> responsecode: " << httpStatus << endl;
	return 0;
}
